﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Tracy.DataModel;
using System.Xml;
using SharedLib.Helpers;
using System.Text.RegularExpressions;
using System.IO;
using Tracy;
using Tracy.DataAccess;
using Tracy.Messages;
using SharedLib.MessageFramework;
using TracyGUI.View.UIComponent;
using SharedLib;
using Microsoft.Practices.Unity;
using SharedLib.WinFormMVCFramework;
namespace TracyGUI.View
{
    public partial class FormEntry : WinFormViewBase, IEntryView
    {
        string initial_search_text;
        Entry _entryToEdit = null;
        bool _loadCompleted = false;
        bool _editCompleted = false;
        bool _hasChange = false;
        bool _editMode = true;
        public FormEntry()
        {
            InitializeComponent();
            this.Icon = SharedResource.Tracy;
            InitColumns();
            initial_search_text = Tracy.TracyFacade.Instance.LanguageManager.GetText("InitialSearchText") ?? "Enter Search Keywords Here";
        }

        private void InitColumns()
        {
            listViewSearchResult.AddColumn("Count",TracyFacade.Instance.LanguageManager.GetText("ColumnName_Count") , ListViewColumnSorter.COLUMN_TYPE_NUM);
            listViewSearchResult.AddColumn("Source", TracyFacade.Instance.LanguageManager.GetText("ColumnName_Source"));
            listViewSearchResult.AddColumn("FanSubGroup", TracyFacade.Instance.LanguageManager.GetText("ColumnName_FanSubGroup"));
            listViewSearchResult.AddColumn("Resolution", TracyFacade.Instance.LanguageManager.GetText("ColumnName_Resolution"));
            listViewSearchResult.AddColumn("Format", TracyFacade.Instance.LanguageManager.GetText("ColumnName_Format"));
            listViewSearchResult.AddColumn("Example", TracyFacade.Instance.LanguageManager.GetText("ColumnName_Example")).Width = 405;
        }

        private void FormEntry_Load(object sender, EventArgs e)
        {
            _loadCompleted = true;
        }

        private void FormEntry_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (_hasChange && !_editCompleted)
            {
                System.Windows.Forms.DialogResult result = MessageBox.Show(TracyFacade.Instance.LanguageManager.GetText("MessageBox_ChangeNotSaved_Message"), TracyFacade.Instance.LanguageManager.GetText("MessageBox_ChangeNotSaved_Title"), MessageBoxButtons.OKCancel);
                if (result == System.Windows.Forms.DialogResult.OK)
                {
                    DialogResult = System.Windows.Forms.DialogResult.Cancel;
                }
                else
                {
                    e.Cancel = true;
                }
            }
        }

        #region IFormEntry Members
        public event EventHandler<GenericEventArgs<Entry>> EntryChanging;
        public event EventHandler<GenericEventArgs<Entry>> Search;
        public event EventHandler<EnhancedEventArgs> FilterSetContextMenuOpening;
        public event EventHandler<GenericEventArgs<FilterSet>> FilterSetMatchedResultsShowing;

        List<FilterSet> _selectedFilterSets = new List<FilterSet>();
        public List<FilterSet> SelectedFilterSets
        {
            get { return _selectedFilterSets; }
            private set { _selectedFilterSets = value; }
        }
        
        #region UI Operations
        public void PrepareForEntryCreation()
        {
            InvokeOnUIThread(() =>
            {
                _editMode = false;
                textBoxName.Text = "";
                textBoxRomaji.Text = "";
                textBoxKeywords.Text = initial_search_text;
                textBoxPath.Text = TracyFacade.Instance.UserPreferencesManager.SavePath;
                textBoxRegex.Text = "";
                checkBoxStopTracing.Checked = false;
                listViewSearchResult.Items.Clear();
                textBoxKeywords.SelectAll();
            });
        }

        public void LoadEntry(Entry entry)
        {
            _entryToEdit = entry;
            RefreshEntry(entry);
        }

        public void RefreshEntry(Entry entry)
        {
            InvokeOnUIThread(() =>
            {
                textBoxName.Text = entry.Name;
                textBoxRomaji.Text = entry.Romaji;
                textBoxKeywords.Text = entry.SearchKeywords;
                textBoxPath.Text = entry.SavePath;
                textBoxRegex.Text = entry.RegExpr;
                checkBoxStopTracing.Checked = entry.TracingDisabled;
            });
        }

        public void LoadFilterSets(List<FilterSet> filterSetList, List<bool> selectedList, List<string> countList, List<string> exampleList)
        {
            InvokeOnUIThread(() =>
            {
                listViewSearchResult.Items.Clear();
                for(int i = 0; i < filterSetList.Count; i++){
                    AddFilterSetItem(filterSetList[i], (selectedList == null) ? true : selectedList[i], (countList == null) ? "N/A" : countList[i], (exampleList == null) ? "N/A" : exampleList[i]);
                }
            });
        }
        #endregion
        
        #endregion

        #region Private Functions
        //private void BuildListViewSubItem(ListViewItem lvItem, string name, string text)
        //{
        //    ListViewItem.ListViewSubItem lvItemSub = new ListViewItem.ListViewSubItem(lvItem, text);
        //    lvItemSub.Name = name;
        //    lvItem.SubItems.Add(lvItemSub);
        //}

        private void AddFilterSetItem(FilterSet filterSet, bool selected, string count, string example)
        {
            ListViewItem lvItemFilterSet = new ListViewItem();
            lvItemFilterSet.Name = "Object";
            lvItemFilterSet.Tag = filterSet;
            lvItemFilterSet.Checked = selected;

            EnhancedListView.AddSubListViewItem(lvItemFilterSet, "Count", count);
            EnhancedListView.AddSubListViewItem(lvItemFilterSet, "Source", filterSet.FeedSource.Name);
            EnhancedListView.AddSubListViewItem(lvItemFilterSet, "FanSubGroup", FanSubGroup.GetCombinationName(filterSet.FanSubGroups));
            EnhancedListView.AddSubListViewItem(lvItemFilterSet, "Resolution", filterSet.Resolution.Name);
            EnhancedListView.AddSubListViewItem(lvItemFilterSet, "Format", filterSet.Format.Name);
            EnhancedListView.AddSubListViewItem(lvItemFilterSet, "Example", example);

            listViewSearchResult.Items.Add(lvItemFilterSet);
        }

        /// <summary>
        /// Generate Entry according to current input
        /// </summary>
        private Entry GenerateEntry()
        {
            Entry rtn;
            if (_entryToEdit == null)
            {
                rtn = new Entry();
            }
            else
            {
                rtn = _entryToEdit;
            }

            rtn.Name = textBoxName.Text;
            rtn.Romaji = textBoxRomaji.Text;
            rtn.SearchKeywords = textBoxKeywords.Text;
            rtn.SavePath = textBoxPath.Text;
            rtn.RegExpr = textBoxRegex.Text;
            rtn.TracingDisabled = checkBoxStopTracing.Checked;

            return rtn;
        }
        #endregion

        #region UI Interactions
        private void buttonDone_Click(object sender, EventArgs e)
        {
            if (String.IsNullOrEmpty(textBoxName.Text))
            {
                MessageBox.Show(TracyFacade.Instance.LanguageManager.GetText("MessageBox_EntryNameEmpty_Message"));
                return;
            }
            Entry editedEntry = GenerateEntry();
            DialogResult = System.Windows.Forms.DialogResult.OK;
            _editCompleted = true;
            Close();
            EntryChanging.InvokeEvent(this, new GenericEventArgs<Entry>(editedEntry));
            
        }

        private void buttonSearch_Click(object sender, EventArgs e)
        {
            TriggerSearch();
        }

        private void textBoxKeywords_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                TriggerSearch();
            }
        }

        private void TriggerSearch()
        {
            if (String.IsNullOrEmpty(textBoxKeywords.Text) || textBoxKeywords.Text == initial_search_text)
            {
                MessageBox.Show(TracyFacade.Instance.LanguageManager.GetText("MessageBox_EntrySearchKeyword_Message"));
                return;
            }
            Entry searchEntry = GenerateEntry();
            Search.InvokeEvent(this, new GenericEventArgs<Entry>(searchEntry));
        }

        private void contextMenuStripSearchResult_Opening(object sender, CancelEventArgs e)
        {
            e.Cancel = true;
            if (listViewSearchResult.SelectedItems.Count > 0)
            {
                ListViewItem item = listViewSearchResult.SelectedItems[0];
                if (item.Tag != null && item.Tag is FilterSet)
                {
                    FilterSet fs = item.Tag as FilterSet;
                    EnhancedEventArgs args = new EnhancedEventArgs();
                    args.Attributes.Add("filter-set", fs);
                    args.Attributes.Add("cancel-event-args", e);
                    FilterSetContextMenuOpening.InvokeEvent(this, args);
                }
            }
        }

        private void matchedResourcesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (listViewSearchResult.SelectedItems.Count > 0)
            {
                ListViewItem item = listViewSearchResult.SelectedItems[0];
                if (item.Tag != null && item.Tag is FilterSet)
                {
                    FilterSet fs = item.Tag as FilterSet;
                    FilterSetMatchedResultsShowing.InvokeEvent(this, new GenericEventArgs<FilterSet>(fs));
                }
            }

        }
        #endregion

        #region ChangeFlag
        private void SetChangeFlag()
        {
            if (_loadCompleted)
            {
                _hasChange = true;
                buttonDone.Enabled = true;
            }
        }

        private void textBoxKeywords_TextChanged(object sender, EventArgs e)
        {
            if (_editMode)
            {
                SetChangeFlag();
            }
        }

        private void textBoxName_TextChanged(object sender, EventArgs e)
        {
            SetChangeFlag();
        }

        private void textBoxRomaji_TextChanged(object sender, EventArgs e)
        {
            SetChangeFlag();
        }

        private void textBoxPath_TextChanged(object sender, EventArgs e)
        {
            SetChangeFlag();
        }

        private void textBoxRegex_TextChanged(object sender, EventArgs e)
        {
            SetChangeFlag();//TODO: validate expression
        }

        private void listViewSearchResult_ItemChecked(object sender, ItemCheckedEventArgs e)
        {
            SetChangeFlag();
            FilterSet filterSet = e.Item.Tag as FilterSet;
            if (filterSet != null)
            {
                if (e.Item.Checked)
                {

                    if (!SelectedFilterSets.Contains(filterSet))
                    {
                        SelectedFilterSets.Add(filterSet);
                    }
                }
                else
                {
                    if (SelectedFilterSets.Contains(filterSet))
                    {
                        SelectedFilterSets.Remove(filterSet);
                    }
                }
            }
        }

        private void buttonBrowsePath_Click(object sender, EventArgs e)
        {
            if (Directory.Exists(textBoxPath.Text))
            {
                folderBrowserDialogEntryFolder.SelectedPath = textBoxPath.Text;
            }
            else
            {
                folderBrowserDialogEntryFolder.SelectedPath = TracyFacade.Instance.UserPreferencesManager.SavePath;
            }
            if (folderBrowserDialogEntryFolder.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                textBoxPath.Text = folderBrowserDialogEntryFolder.SelectedPath;
            }
        }

        private void textBoxKeywords_MouseClick(object sender, MouseEventArgs e)
        {
            if (textBoxKeywords.Text == initial_search_text)
            {
                textBoxKeywords.SelectAll();
            }
        }

        

        private void checkBoxStopTracing_CheckedChanged(object sender, EventArgs e)
        {
            SetChangeFlag();
        }
        #endregion


    }
}
